package com.nlelpct.enums;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author :小马
 * @date : 2022-09-08
 */
public enum ThreadPool {
    /**
     * 等待任务超过队列时由主线程执行，当主线程获得任务时会优先执行分配的任务。尽量不要超过实际的任务队列数量
     */
    CallerRunsPolicy(new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() * 2 + 1, 120L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().setNameFormat("caller_runs_policy_pool-%d").build(),
            new ThreadPoolExecutor.CallerRunsPolicy())),
    /**
     * 丢弃老的任务
     */
    DiscardOldestPolicy(new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() * 2 + 1, 120L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().setNameFormat("discard_oldest_policy_pool-%d").build(),
            new ThreadPoolExecutor.DiscardOldestPolicy())),
    /**
     * 丢弃任务
     */
    DiscardPolicy(new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() * 2 + 1, 120L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().setNameFormat("discard_policy_pool-%d").build(),
            new ThreadPoolExecutor.DiscardPolicy())),
    /**
     * 等待任务超过队列时丢弃并抛出异常，中断操作
     */
    AbortPolicy(new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() * 2 + 1, 120L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().setNameFormat("abort_policy_pool-%d").build(),
            new ThreadPoolExecutor.AbortPolicy()));
    public ExecutorService pool;

    ThreadPool(ExecutorService pool) {
        this.pool = pool;
    }

    public ExecutorService getPool() {
        return pool;
    }
}
